package com.ld.poetry.service.impl;

import com.alibaba.dashscope.aigc.generation.Generation;

import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.aigc.generation.models.QwenParam;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.MessageManager;
import com.alibaba.dashscope.common.ResultCallback;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.ld.poetry.service.DataReceivedCallback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;


import java.util.Arrays;
import java.util.concurrent.Semaphore;

/**
 * 新增功能，通义千问对话聊天
 * 使用sse 实时返回结果
 * created by vital on 2024/11/18 下午5:47
 */
@Slf4j
@Service
public class QianwenService {


    // 阿里云 API Key
    @Value("${poetry.qianwen.apikey}")
    private String apikey;

    /**
     * 异步调用，通过回调函数获取结果
     * @param gen
     * @param userMsg
     * @param callback 回调函数
     * @throws NoApiKeyException
     * @throws ApiException
     * @throws InputRequiredException
     * @throws InterruptedException
     */
    public void streamCallWithCallback(Generation gen, Message systemMsg, Message userMsg, DataReceivedCallback callback)
            throws NoApiKeyException, ApiException, InputRequiredException, InterruptedException {
        Constants.apiKey=this.apikey;


        //构造API请求参数

        GenerationParam param = buildGenerationParam(systemMsg,userMsg);

        //初始化一个信号量，用于在异步操作完成后通知主线程
        Semaphore semaphore = new Semaphore(0);
        //累积从API接收的所有消息内容
        StringBuilder fullContent = new StringBuilder();

        // 调用API，并通过回调函数返回结果
        gen.streamCall(param, new ResultCallback<GenerationResult>() {
            //有结果响应时：
            @Override
            public void onEvent(GenerationResult message) {
                //返回每次接收到的消息
                callback.onDataReceived(message.getOutput().getChoices().get(0).getMessage().getContent());
            }
            //异常处理
            @Override
            public void onError(Exception err) {
                log.error("通义千问错误：", err.getMessage());
                semaphore.release();
            }

            //API调用完全结束后
            @Override
            public void onComplete() {
                log.info("Completed");
                semaphore.release();
            }
        });

        // 主线程在此等待，直到信号量被释放。
        semaphore.acquire();
    }

    /**
     * 构造API请求参数
     * @param userMsg
     * @return
     */
    private  GenerationParam buildGenerationParam(Message systemMsg,Message userMsg) {
        return GenerationParam.builder()
                .model("qwen-turbo")
                .messages(Arrays.asList(systemMsg,userMsg))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .topP(0.8)
                .incrementalOutput(true)
                .build();
    }

//    /**
//     * 单次聊天，一次性传输消息
//     * @param message
//     * @return
//     * @throws NoApiKeyException
//     * @throws InputRequiredException
//     */
//    public String chat(String message) throws NoApiKeyException, InputRequiredException {
//        //设置apikey
//        Constants.apiKey=apikey;
//        Generation gen = new Generation();
//        MessageManager msgManager = new MessageManager(10);
//        Message systemMsg = Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build();
//        Message userMsg = Message.builder().role(Role.USER.getValue()).content(message).build();
//        msgManager.add(systemMsg);
//        msgManager.add(userMsg);
//        QwenParam param =
//                QwenParam.builder().model(Generation.Models.QWEN_TURBO).messages(msgManager.get())
//                        .resultFormat(QwenParam.ResultFormat.MESSAGE)
//                        .build();
//        GenerationResult result = gen.call(param);
//        System.out.println(result.getOutput().getChoices().getFirst().getMessage().getContent());
//        return String.valueOf(result.getOutput().getChoices().getFirst().getMessage().getContent());
//    }

}
